<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html lang="ru" xml:lang="ru">

<head>
  <meta http-equiv="Content-type" content="text/html; charset=windows-1251" />
  <title>Basis Test Suite - Buildin classes &amp; objects extensions &amp; fix</title>

  <style type="text/css">
    @import "style/default/style.css";

    /* */
    BODY
    {
      font-family: Georgia;
      font-size: small;
      _font-size: x-small;
    }
  </style>
  
  <script type="text/javascript"  src="../basis.js"></script>
  <script type="text/javascript"  src="../data.js"></script>
  <script type="text/javascript"  src="../property.js"></script>
  <script type="text/javascript"  src="../dom_wrapper.js"></script>
  <script type="text/javascript"  src="test.js"></script>
  <script type="text/javascript"  src="common.js"></script>
</head>

<body>
  <script type="text/javascript">
    loadTest((function(){
      var Data = Basis.Data;

      var A = [1,2,3,4,5];
      var B = [5,4,3,2,1];
      var C = [1,2,3];
      var D = [4,5];
      var E = [1,2,3,2,3,2,1];
      var T;

      return [
        {
          name: 'Array',
          testcase: [
            {
              name: 'Class methods',
              testcase: [
                {
                  name: 'Array.from()',
                  test: function(){
                    this.is(A, Array.from(A));
                    this.is(false, A === Array.from(A));
                  }
                },
                {
                  name: 'Array.create()',
                  test: function(){
                    this.is([undefined, undefined, undefined], Array.create(3));

                    this.is([1,1,1], Array.create(3, 1));

                    this.is(['1','1','1'], Array.create(3, '1'));

                    this.is([], Array.create());

                    this.is([0,1,2], Array.create(3, Function.$self));
                    this.is([true,true,true], Array.create(3, Function.$true));
                  }
                }/*,
                {
                  name: 'Array.matrix()',
                  test: function(){
                    var M = Array.matrix(2,3);
                    this.is(2, M.length);
                    this.is(3, M[0].length);
                    this.is(3, M[1].length);

                    var M = Array.matrix(2,3,4);
                    this.is(2, M.length);
                    this.is(3, M[0].length);
                    this.is(4, M[0][0].length);
                  }
                }*/
              ]
            },
            {
              name: 'Buildin',
              testcase: [
                {
                  name: 'push()',

                  test: function(){
                    var T = Array.from(D);
                    this.is(2, T.push());
                    this.is([4,5], T);

                    var T = Array.from(D);
                    this.is(3, T.push(6));
                    this.is([4,5,6], T);

                    var T = Array.from(D);
                    this.is(4, T.push(6,7));
                    this.is([4,5,6,7], T);
                  }
                },
                {
                  name: 'pop()',
                  test: function(){
                    var T = Array.from(D);
                    this.is(5, T.pop())
                    this.is([4], T);

                    var T = Array.from(D);
                    this.is(5, T.pop(3))
                    this.is([4], T);
                  }
                },
                {
                  name: 'unshift()',
                  test: function(){
                    var T = Array.from(D);
                    this.is(2, T.unshift())
                    this.is([4, 5], T);

                    var T = Array.from(D);
                    this.is(3, T.unshift(3))
                    this.is([3, 4, 5], T);

                    var T = Array.from(D);
                    this.is(5, T.unshift(1, 2, 3))
                    this.is([1, 2, 3, 4, 5], T);
                  }
                },
                {
                  name: 'shift()',
                  test: function(){
                    var T = Array.from(D);
                    this.is(4, T.shift())
                    this.is([5], T);

                    var T = Array.from(D);
                    this.is(4, T.shift(3))
                    this.is([5], T);
                  }
                },
                {
                  name: 'splice()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is(A, T.splice(0));
                    this.is([], T);

                    var T = [1,2,3,4,5];;
                    this.is(D, T.splice(3));
                    this.is(C, T);

                    var T = [1,2,3,4,5];;
                    this.is([], T.splice(3,0));
                    this.is(A, T);

                    var T = [1,2,3,4,5];;
                    this.is([3,4], T.splice(2,2));
                    this.is([1,2,5], T);

                    var T = [1,2,3,4,5];;
                    this.is([], T.splice(20,2));
                    this.is(A, T);

                    var T = [1,2,3,4,5];;
                    this.is([], T.splice(5, 0, 6));
                    this.is([1,2,3,4,5,6], T);

                    var T = [1,2,3,4,5];;
                    this.is([1,2], T.splice(0, 2, 7, 7));
                    this.is([7,7,3,4,5], T);

                    var T = [1,2,3,4,5];;
                    this.is(A, T.splice(0, 20, 7, 7));
                    this.is([7,7], T);
                  }
                },
                {
                  name: 'slice()',
                  test: function(){

                    var T = Array.from(C);
                    this.is(C, T.slice());
                    this.is(C, T);

                    var T = [1,2,3,4,5];;
                    this.is(D, T.slice(3));
                    this.is(A, T);

                    var T = [1,2,3,4,5];;
                    this.is(C, T.slice(0,3));
                    this.is(A, T);

                    var T = [1,2,3,4,5];;
                    this.is([1,2], T.slice(0,-3));
                    this.is(A, T);

                  }
                }
              ]
            },
            {
              name: 'JavaScript 1.6',
              testcase: [
                {
                  name: 'indexOf()',
                  test: function(){
                    this.is(-1, E.indexOf());
                    this.is(2,  E.indexOf(3));
                    this.is(4,  E.indexOf(3, 3));
                    this.is(4,  E.indexOf(3, 4));
                    this.is(-1, E.indexOf(3, 5));
                    this.is(-1, E.indexOf('3'));
                    this.is(-1, E.indexOf(33));
                  }
                },
                {
                  name: 'lastIndexOf()',
                  test: function(){
                    this.is(-1, E.lastIndexOf());
                    this.is(4,  E.lastIndexOf(3));
                    this.is(-1, E.lastIndexOf('3'));
                    this.is(-1, E.lastIndexOf(33));
                  }
                },
                {
                  name: 'forEach()',
                  test: function(){
                    var tmp = '';
                    var T = Array.from(C);
                    // must return array or undefined???
                    this.is(undefined, T.forEach(function(item){ tmp += item * 2 }));
                    this.is(C, T, true);

                    this.is('246', tmp);

                    var T = Array.from(C);
                    T.forEach(function(item, index, array){ array[index] *= 2 });
                    this.is([2,4,6], T);
                  }
                },
                {
                  name: 'every()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is(true,  T.every(function(item){ return item > 0 }));
                    this.is(A, T, true);

                    this.is(false, T.every(function(item){ return item > 1 }));

                    T[100] = 1;
                    this.is(true, T.every(function(item){ return typeof item != 'undefined' }));

                    var counter = 0;
                    this.is(true, T.every(function(item){ counter++; return true }));
                    this.is(A.length + 1, counter);
                  }
                },
                {
                  name: 'some()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is(true,  T.some(function(item){ return item > 4 }));
                    this.is(A, T, true);

                    this.is(false, T.some(function(item){ return item > 10 }));

                    T[100] = 1;
                    this.is(false, T.some(function(item){ return typeof item == 'undefined' }));

                    var counter = 0;
                    this.is(false, T.some(function(item){ counter++; return false }));
                    this.is(A.length + 1, counter);
                  }
                },
                {
                  name: 'filter()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is([1,3,5], T.filter(function(item){ return item % 2 }));
                    this.is(A, T, true);

                    T[100] = 1;
                    this.is([1,2,3,4,5,1], T.filter(Function.$true));
                    this.is([1,2,3,4,5,1], T.filter(Function.$self));

                    this.is([], T.filter(Function.$false));

                    var counter = 0;
                    this.is([], T.filter(function(item){ counter++ }));
                    this.is(A.length + 1, counter);
                  }
                },
                {
                  name: 'map()',
                  test: function(){
                    var T = Array.from(C);
                    this.is([2,4,6], T.map(function(item){ return item * 2 }));
                    this.is(T, C, true);

                    T[5] = 1;
                    this.is([2,4,6,undefined,undefined,2], T.map(function(item){ return item * 2 }));

                    var counter = 0;
                    this.is([undefined, undefined, undefined, undefined, undefined, undefined], T.map(function(item){ counter++ }));
                    this.is(4, counter);
                  }
                },
                {
                  name: 'reduce()',
                  test: function(){
                    var T = [0,1,2,3,4];
                    this.is(10, T.reduce(function(previousValue, currentValue, index, array){
                      return previousValue + currentValue;
                    }));
                    this.is([0,1,2,3,4], T);

                    this.is(20, T.reduce(function(previousValue, currentValue, index, array){
                      return previousValue + currentValue;
                    }, 10));

                    var T = [[0,1], [2,3], [4,5]];
                    this.is([0,1,2,3,4,5], T.reduce(function(a, b){
                      return a.concat(b);
                    }, []));
                  }
                }
              ]
            },
            {
              name: 'Extractors',
              testcase: [
                {
                  name: 'clone()',
                  test: function(){
                    var T = [1,2,3];
                    this.is(T, T.clone());
                    this.is(true, T !== T.clone());
                  }
                },
                {
                  name: 'flatten()',
                  test: function(){
                    this.is([0,1,2,3,3.5,4,5,6], [0, C, 3.5, D, 6].flatten());

                    var T = [1,2,3];
                    this.is([1,T,2,2,T,3], [[1,T,2],2,[T,3]].flatten());

                    var T = [];
                    this.is([1,2], [1,T,2].flatten());
                    this.is([1,T,2], [1,[T],2].flatten());
                  }
                },
                {
                  name: 'unique()',
                  test: function(){
                    var T = Array.from(E);
                    this.is(C, T.unique());
                    this.is(T, E);

                    this.is([1,2,3,'1','2'], [1,2,3,'1',1,2,'1',3,'2'].unique());
                  }
                },
                {
                  name: 'collapse()',
                  test: function(){
                    var T = [1,2,3,4,5];

                    this.is([1,3,5], T.collapse(function(item){ return !(item % 2) }));
                    this.is([1,3,5], T);

                    var T = [1,2,3,4,5];
                    this.is([], T.collapse(Function.$true));

                    var T = [1,2,3,4,5];
                    this.is(T, T.collapse(Function.$false));

                    var T = [1,2,3,4,5];
                    T[10] = 1;
                    this.is([1,2,3,4,5,1], T.collapse(Function.$isNull));

                    var T = [1,2,3,4,5];
                    T[10] = 1;
                    this.is([undefined,undefined,undefined,undefined,undefined], T.collapse(Function.$isNotNull));

                    var T = [1,2,3,4,5,0];
                    T[10] = 1;
                    this.is([0,undefined,undefined,undefined,undefined], T.collapse(Function.$self));
                  }
                },
                {
                  name: 'exclude()',
                  test: function(){
                    var T = [1,2,3,4,5];

                    //this.is(undefined, T.exclude()); // exception thrown

                    this.is(T, T.exclude([]));
                    this.is(false, T === T.exclude([]));

                    this.is([2,3], T.exclude([5,4,1]));
                    this.is([2,3,4,5], T.exclude([1,1,1]));
                    this.is(T, T.exclude([6,7,8]));
                  }
                },
                /*{
                  name: 'call()',
                  test: function(){
                    var T = [1,2,3,4,5];
                    this.is(T, T.call(Function.$self));

                    var oddCount = 0;
                    this.is(T, T.call(function(){ oddCount += this % 2 }));
                    this.is(3, oddCount);

                    var oddCount = 0;
                    this.is(T, T.call(function(a, b){ oddCount += (this + a + b) % 2 }, 1, 2));
                    this.is(2, oddCount);

                    var count = 0;
                    var c = function(value){ this.value = value };
                    c.prototype.count = function(){ count += this.value };
                    var T = [new c(1), new c(2), new c(3)];
                    this.is(T, T.call(c.prototype.count));
                    this.is(6, count);
                  }
                },*/
                {
                  name: 'repeat()',
                  test: function(){
                    this.is([], [].repeat());
                    this.is([], [].repeat(0));
                    this.is([], [].repeat(3));

                    this.is([], [1].repeat());
                    this.is([], [1].repeat(0));
                    this.is([1,1,1], [1].repeat(3));

                    this.is([], [1,2,3].repeat());
                    this.is([], [1,2,3].repeat(0));
                    this.is([1,2,3,1,2,3,1,2,3], [1,2,3].repeat(3));
                  }
                },
                {
                  name: 'item()',
                  test: function(){
                    var T = [0,1,2,3,4,5];
                    this.is(0, T.item());
                    this.is(3, T.item(3));
                    this.is(4, T.item(4));
                    this.is(3, T.item(-3));
                    this.is(2, T.item(-4));
                    this.is(0, T.item(-6));
                    this.is(undefined, T.item(6));
                    this.is(undefined, T.item(-7));
                  }
                },
                /*{
                  name: 'firstIndex()',
                  test: function(){
                    var T = [0,1,2,3,4,5];
                    this.is(0, T.firstIndex());
                    this.is(0, T.firstIndex(0));
                    this.is(0, T.firstIndex(0.5));
                    this.is(3, T.firstIndex(3));
                    this.is(3, T.firstIndex(3.1));
                    this.is(3, T.firstIndex(3.999));

                    var T = [];
                    T[3] = 3;
                    T[7] = 5;
                    this.is(3, T.firstIndex());
                    this.is(3, T.firstIndex(0));
                    this.is(3, T.firstIndex(0.5));
                    this.is(7, T.firstIndex(1));
                    this.is(7, T.firstIndex(1.1));
                    this.is(7, T.firstIndex(1.99));

                    this.is(-1, T.firstIndex(2));
                    this.is(-1, T.firstIndex(-1));
                  }
                },*/
                {
                  name: 'first()',
                  test: function(){
                    /*var T = [0,1,2,3,4,5];
                    this.is(0, T.first());
                    this.is(0, T.first(0));
                    this.is(0, T.first(0.5));
                    this.is(3, T.first(3));
                    this.is(3, T.first(3.1));
                    this.is(3, T.first(3.999));

                    var T = [];
                    T[3] = 3;
                    T[7] = 5;
                    this.is(3, T.first());
                    this.is(3, T.first(0));
                    this.is(3, T.first(0.5));
                    this.is(5, T.first(1));
                    this.is(5, T.first(1.1));
                    this.is(5, T.first(1.99));

                    this.is(undefined, T.first(2));
                    this.is(undefined, T.first(-1));*/
                  }
                },
                /*{
                  name: 'lastIndex()',
                  test: function(){
                    var T = [0,1,2,3,4,5];
                    this.is(5, T.lastIndex());
                    this.is(5, T.lastIndex(0));
                    this.is(5, T.lastIndex(0.5));
                    this.is(2, T.lastIndex(3));
                    this.is(2, T.lastIndex(3.1));
                    this.is(2, T.lastIndex(3.999));

                    var T = [];
                    T[3] = 3;
                    T[7] = 5;
                    this.is(7, T.lastIndex());
                    this.is(7, T.lastIndex(0));
                    this.is(7, T.lastIndex(0.5));
                    this.is(3, T.lastIndex(1));
                    this.is(3, T.lastIndex(1.1));
                    this.is(3, T.lastIndex(1.99));

                    this.is(-1, T.lastIndex(2));
                    this.is(-1, T.lastIndex(-1));
                  }
                },*/
                {
                  name: 'last()',
                  test: function(){
                    /*var T = [0,1,2,3,4,5];
                    this.is(5, T.last());
                    this.is(5, T.last(0));
                    this.is(5, T.last(0.5));
                    this.is(2, T.last(3));
                    this.is(2, T.last(3.1));
                    this.is(2, T.last(3.999));

                    var T = [];
                    T[3] = 3;
                    T[7] = 5;
                    this.is(5, T.last());
                    this.is(5, T.last(0));
                    this.is(5, T.last(0.5));
                    this.is(3, T.last(1));
                    this.is(3, T.last(1.1));
                    this.is(3, T.last(1.99));

                    this.is(undefined, T.last(2));
                    this.is(undefined, T.last(-1));*/
                  }
                },
                {
                  name: 'search()',
                  test: function(){
                    var T = [{ value: 0 },{ value: 1 },{ value: 2 },{ value: 3 },{ value: 4 },{ value: 2, b: 1 }];
                    this.is(undefined, T.search(2));
                    this.is(T[1], T.search(T[1]));
                    this.is(T[1], T.search(1.0, Function.getter('value')));
                    this.is(undefined, T.search(1.5, Function.getter('value')));
                    this.is(undefined, T.search('2', Function.getter('value')));
                    this.is(T[2], T.search(2, Function.getter('value')));
                    this.is(T.last(), T.search(2, Function.getter('value'), 3));
                    this.is(T.last(), T.search(2, 'value', 3));

                    var T = [];
                    T[3] = { value: 3 };
                    T[7] = { value: 5 };
                    T[9] = { value: 3 };
                    this.is(undefined, T.search(2));
                    this.is(undefined, T.search(2, Function.getter('value')));
                    this.is(T[3], T.search(3.0, Function.getter('value')));
                    this.is(undefined, T.search(1.5, Function.getter('value')));
                    this.is(undefined, T.search('3', Function.getter('value')));
                    this.is(T[3], T.search(3, Function.getter('value')));
                    this.is(T[9], T.search(3, Function.getter('value'), 4));
                  }
                },
                {
                  name: 'lastSearch()',
                  test: function(){
                    var T = [{ value: 0 },{ value: 1 },{ value: 2 },{ value: 3 },{ value: 4 },{ value: 2, b: 1 }];
                    this.is(undefined, T.lastSearch(2));
                    this.is(T[1], T.lastSearch(T[1]));
                    this.is(T[1], T.lastSearch(1.0, Function.getter('value')));
                    this.is(undefined, T.lastSearch(1.5, Function.getter('value')));
                    this.is(undefined, T.lastSearch('2', Function.getter('value')));
                    this.is(T.last(), T.lastSearch(2, Function.getter('value')));
                    this.is(T[2], T.lastSearch(2, Function.getter('value'), 3));
                    this.is(T[2], T.lastSearch(2, 'value', 3));
                    this.is(T[2], T.lastSearch(2, 'value', 4));
                    this.is(T.last(), T.lastSearch(2, 'value', 5));

                    var T = [];
                    T[3] = { value: 3 };
                    T[7] = { value: 5 };
                    T[9] = { value: 3 };
                    this.is(undefined, T.lastSearch(2));
                    this.is(undefined, T.lastSearch(2, Function.getter('value')));
                    this.is(T[9], T.lastSearch(3.0, Function.getter('value')));
                    this.is(undefined, T.lastSearch(1.5, Function.getter('value')));
                    this.is(undefined, T.lastSearch('3', Function.getter('value')));
                    this.is(T[9], T.lastSearch(3, Function.getter('value')));
                    this.is(T[3], T.lastSearch(3, Function.getter('value'), 4));
                  }
                }
              ]
            },
            {
              name: 'Ordered for',
              testcase: [
                {
                  name: 'binarySearchPos()',
                  test: function(){
                    var T = [0,1,2,3,4];
                    this.is(0, T.binarySearchPos(-1));
                    this.is(-1, T.binarySearchPos(-1, null, false, true));
                    this.is(0, T.binarySearchPos(0));
                    this.is(1, T.binarySearchPos(1));
                    this.is(2, T.binarySearchPos(1.5));
                    this.is(-1, T.binarySearchPos(1.5, null, false, true));
                    this.is(2, T.binarySearchPos(2));
                    this.is(4, T.binarySearchPos(4));
                    this.is(5, T.binarySearchPos(5));
                    this.is(-1, T.binarySearchPos(5, null, false, true));
                         // 0 1 2 3 4 5
                    var T = [4,3,2,1,0];
                    this.is(5, T.binarySearchPos(-1, null, true));
                    this.is(-1, T.binarySearchPos(-1, null, true, true));
                    this.is(4, T.binarySearchPos(0, null, true));
                    this.is(3, T.binarySearchPos(1, null, true));
                    this.is(3, T.binarySearchPos(1.5, null, true));
                    this.is(-1, T.binarySearchPos(1.5, null, true, true));
                    this.is(2, T.binarySearchPos(2, null, true));
                    this.is(0, T.binarySearchPos(4, null, true));
                    this.is(0, T.binarySearchPos(5, null, true));
                    this.is(-1, T.binarySearchPos(5, null, true, true));

                    var T = [{ a: 0 }, { a: 1}, { a: 2 }, { a: 3 }, { a: 4 }];
                    this.is(0, T.binarySearchPos(-1,  'a'));
                    this.is(0, T.binarySearchPos(0,   'a'));
                    this.is(-1, T.binarySearchPos(0,  'b'));
                    this.is(-1, T.binarySearchPos({},  'a'));
                    this.is(-1, T.binarySearchPos(null,  'a'));
                    this.is(1, T.binarySearchPos(1,   'a'));
                    this.is(2, T.binarySearchPos(1.5, 'a'));
                    this.is(-1, T.binarySearchPos(1.5, 'a', false, true));
                    this.is(2, T.binarySearchPos(2,   'a'));
                    this.is(4, T.binarySearchPos(4,   'a'));
                    this.is(5, T.binarySearchPos(5,   Function.getter('a')));
                  }
                },
                {
                  name: 'binarySearch()',
                  test: function(){
                    var T = [0,1,2,3,4];
                    this.is(-1, T.binarySearch(-1));
                    this.is(0,  T.binarySearch(0));
                    this.is(1,  T.binarySearch(1));
                    this.is(-1, T.binarySearch(1.5));
                    this.is(2,  T.binarySearch(2));
                    this.is(4,  T.binarySearch(4));
                    this.is(-1, T.binarySearch(5));

                    var T = [{ a: 0 }, { a: 1}, { a: 2 }, { a: 3 }, { a: 4 }];
                    this.is(-1, T.binarySearch(-1,  Function.getter('a')));
                    this.is(0,  T.binarySearch(0,   Function.getter('a')));
                    this.is(-1, T.binarySearch(0,   Function.getter('b')));
                    this.is(1,  T.binarySearch(1,   Function.getter('a')));
                    this.is(-1, T.binarySearch(1.5, Function.getter('a')));
                    this.is(2,  T.binarySearch(2,   Function.getter('a')));
                    this.is(4,  T.binarySearch(4,   Function.getter('a')));
                    this.is(-1, T.binarySearch(5,   Function.getter('a')));
                  }
                },
                {
                  name: 'binarySearchIntervalPos()',
                  test: function(){
                    var T = [{ l: 0, r: 1 }, { l: 2, r: 3}, { l: 4, r: 5}];
                    var l = Function.getter('l');
                    var r = Function.getter('r');
                    this.is(0, T.binarySearchIntervalPos(-1, l, r));
                    this.is(-1, T.binarySearchIntervalPos(-1, l, r, true));
                    this.is(0, T.binarySearchIntervalPos(0, l, r));
                    this.is(0, T.binarySearchIntervalPos(1, l, r));
                    this.is(1, T.binarySearchIntervalPos(1.5, l, r));
                    this.is(1, T.binarySearchIntervalPos(1.01, l, r));
                    this.is(1, T.binarySearchIntervalPos(1.99, l, r));
                    this.is(-1, T.binarySearchIntervalPos(1.5, l, r, true));
                    this.is(2, T.binarySearchIntervalPos(3.5, l, r));
                    this.is(-1, T.binarySearchIntervalPos(3.5, l, r, true));
                    this.is(3, T.binarySearchIntervalPos(5.5, l, r));
                    this.is(-1, T.binarySearchIntervalPos(3.5, l, r, true));
                    this.is(1, T.binarySearchIntervalPos(2, l, r));
                    this.is(2, T.binarySearchIntervalPos(4, l, r));
                    this.is(2, T.binarySearchIntervalPos(5, l, r));

                    this.is(3, T.binarySearchIntervalPos(5.5, 'l', 'r'));
                    this.is(-1, T.binarySearchIntervalPos(3.5, l, 'r', true));
                    this.is(1, T.binarySearchIntervalPos(2, 'l', r));

                    this.is(1, T.binarySearchIntervalPos(0.7, function(o){ return o.l/2 }, "r/2"));
                    this.is(1, T.binarySearchIntervalPos(1.2, "l/2", function(o){ return o.r/2 }));
                    this.is(2, T.binarySearchIntervalPos(2.5, function(o){ return o.l/2 }, function(o){ return o.r/2 }));
                    this.is(3, T.binarySearchIntervalPos(3,   function(o){ return o.l/2 }, function(o){ return o.r/2 }));
                    this.is(0, T.binarySearchIntervalPos(-5, function(o){ return -o.l }, function(o){ return -o.r }));
                  }
                },
                {
                  name: 'binarySearchInterval()',
                  test: function(){
                    var T = [{ l: 0, r: 1 }, { l: 2, r: 3}, { l: 4, r: 5}];
                    var l = Function.getter('l');
                    var r = Function.getter('r');
                    this.is(-1, T.binarySearchInterval(-1, l, r));
                    this.is(0,  T.binarySearchInterval(0, l, r));
                    this.is(0,  T.binarySearchInterval(1, l, r));
                    this.is(-1, T.binarySearchInterval(1.5, l, r));
                    this.is(1,  T.binarySearchInterval(2, l, r));
                    this.is(2,  T.binarySearchInterval(4, l, r));
                    this.is(-1, T.binarySearchInterval(6, l, r));

                    this.is(0,  T.binarySearchInterval(1, 'l', 'r'));
                    this.is(-1, T.binarySearchInterval(1.5, l, 'r'));
                    this.is(1,  T.binarySearchInterval(2, 'l', r));

                  }
                }
              ]
            },
            {
              name: 'Comparators',
              testcase: [
                {
                  name: 'equal()',
                  test: function(){
                    var TA = Array.from(A);
                    var TB = Array.from(B);
                    var TC = Array.from(C);

                    this.is(A, TB.reverse());
                    this.is(true, TA.equal(TB));
                    this.is(false, TA.equal(TC.reverse()));
                    this.is(false, [1,2,'3'].equal(C));
                  }
                }/* removed from Basis,
                {
                  name: 'same()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is(true,  T.same(B));
                    this.is(false, T.same(E));
                    this.is(A, T);
                  }
                },
                {
                  name: 'similar()',
                  test: function(){
                    this.is(true,  A.similar(B));
                    this.is(true,  C.similar(E));
                    this.is(false, A.similar(C));
                    this.is(false, [1,2,'3'].similar(C));
                  }
                }*/
              ]
            },
            {
              name: 'Collection for',
              testcase: [
                {
                  name: 'add()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is(true,  T.add('3'));
                    this.is(false, T.add(3));
                    this.is(true,  T.add(7));
                  }
                },
                {
                  name: 'remove()',
                  test: function(){
                    var T = [1,2,3,4,5];;
                    this.is(false, T.remove('3'));
                    this.is(true,  T.remove(3));
                    this.is(false, T.remove(7));
                  }
                },
                {
                  name: 'has()',
                  test: function(){
                    var T = [1,2,3,4,5];
                    this.is(false, T.has('3'));
                    this.is(true,  T.has(3));
                    this.is(false, T.has(23));
                  }
                },
                {
                  name: 'absent()',
                  test: function(){
                    var T = [1,2,3,4,5];
                    this.is(true,  T.absent('3'));
                    this.is(false, T.absent(3));
                    this.is(true,  T.absent(23));
                  }
                }
              ]
            },
            {
              name: 'Misc',
              testcase: [
                /*{
                  name: 'roll()',
                  test: function(){
                    var T = [1,2,3,4,5];
                    this.is([1,2,3,4,5], T.roll());

                    var T = [1,2,3,4,5];
                    this.is([1,2,3,4,5], T.roll(0));

                    var T = [1,2,3,4,5];
                    this.is([1,2,3,4,5], T.roll(T.length));

                    var T = [1,2,3,4,5];
                    this.is([1,2,3,4,5], T.roll(-T.length));

                    var T = [1,2,3,4,5];
                    var T2 = T.roll(T.length);
                    this.is(true, T === T2);

                    var T = [1,2,3,4,5];
                    this.is([3,4,5,1,2], T.roll(2));

                    var T = [1,2,3,4,5];
                    this.is([3,4,5,1,2], T.roll(2.1));

                    var T = [1,2,3,4,5];
                    this.is([3,4,5,1,2], T.roll(2.9));

                    var T = [1,2,3,4,5];
                    this.is([3,4,5,1,2], T.roll(T.length + 2));

                    var T = [1,2,3,4,5];
                    this.is([4,5,1,2,3], T.roll(-2));

                    var T = [1,2,3,4,5];
                    this.is([4,5,1,2,3], T.roll(-2.1));

                    var T = [1,2,3,4,5];
                    this.is([4,5,1,2,3], T.roll(-2.9));

                    var T = [1,2,3,4,5];
                    this.is([4,5,1,2,3], T.roll(-T.length - 2));
                  }
                },*/
                {
                  name: 'sortAsObject()',
                  test: function(){
                    ;
                  }
                },
                {
                  name: 'clear()',
                  test: function(){
                    var T = [1,2,3,4,5];
                    this.is([], T.clear());
                    this.is([], T);
                  }
                }
              ]
            }/**/
          ]
        }/*,
        {
          name: 'RegExp',
          testcase: [
            {
              name: 'RegExp.makeGlobal()',
              test: function(){
              }
            },
            {
              name: 'exec()',
              test: function(){
              }
            }
          ]
        },
        {
          name: 'Function',
          testcase: [
            {
              name: 'call()',
              test: function(){
              }
            },
            {
              name: 'apply()',
              test: function(){
              }
            },
            {
              name: 'bind()',
              test: function(){
                
              }
            },
            {
              name: 'fix()',
              test: function(){
                
              }
            },
            {
              name: 'createInstance()',
              test: function(){
                
              }
            },
            {
              name: 'extend()',
              test: function(){
                
              }
            },
            {
              name: 'complete()',
              test: function(){
                
              }
            }
          ]
        }*/,
        {
          name: 'String',
          testcase: [
            {
              name: 'toObject()',
              test: function(){
                this.is({ a: 123, b: 234 }, '{ a: 123, b: 234 }'.toObject());
                this.is([1,2,3,4,5], '[1,2,3,4,5]'.toObject());
                this.is(function(val){return val}.toString(), 'function(val){return val}'.toObject().toString());
              }
            },
            {
              name: 'repeat()',
              test: function(){
                this.is('', ''.repeat());
                this.is('', ''.repeat(0));
                this.is('', ''.repeat(3));

                this.is('', 'a'.repeat());
                this.is('', 'a'.repeat(0));
                this.is('aaa', 'a'.repeat(3));

                this.is('', 'abc'.repeat());
                this.is('', 'abc'.repeat(0));
                this.is('abcabcabc', 'abc'.repeat(3));
              }
            },
            {
              name: 'toArray()',
              test: function(){
                var S = 'hello';
                this.is(["h", "e", "l", "l", "o"], S.toArray());
                this.is([], ''.toArray());

                var S = "\u043F\u0440\u0438\u0432\u0435\u0442";
                this.is(["\u043F","\u0440","\u0438","\u0432","\u0435","\u0442"], S.toArray());
              }
            },
            {
              name: 'qw()',
              test: function(){
                var S = '  foo foo-bar foo:bar bar ';
                this.is(['foo', 'foo-bar', 'foo:bar', 'bar'], S.qw());

                var S = ' \t foo \n\n\nbar\r\n\r';
                this.is(['foo', 'bar'], S.qw());

                this.is([], ''.qw());

                var S = ' \t \n\n\n \r\n\r';
                this.is([], S.qw());
              }
            },
            {
              name: 'forRegExp()',
              test: function(){
              }
            },
            {
              name: 'toRegExp()',
              test: function(){
              
              }
            },
            {
              name: 'sprintf()',
              test: function(){
              
              }
            },
            {
              name: 'format()',
              test: function(){
              
              }
            },
            {
              name: 'ltrim()',
              test: function(){
                this.is('x \n ', ' \n x \n '.trimLeft());
              }
            },
            {
              name: 'rtrim()',
              test: function(){
                this.is(' \n x', ' \n x \n '.trimRight());
              }
            },
            {
              name: 'trim()',
              test: function(){
                this.is('x', ' \n x \n '.trim());
              }
            },
            {
              name: 'ellipsis()',
              test: function(){
                var tail = '\u2026';

                this.is('', ''.ellipsis());
                this.is('', ''.ellipsis(0));
                this.is('', ''.ellipsis(1));
                this.is('', ''.ellipsis(2));
                this.is('', ''.ellipsis(-2));

                var S = 'hello';
                this.is(tail, S.ellipsis());
                this.is(tail, S.ellipsis(0));
                this.is('h' + tail, S.ellipsis(1));
                this.is('he' + tail, S.ellipsis(2));
                this.is('hell' + tail, S.ellipsis(4));
                this.is('hello', S.ellipsis(5));
                this.is('hello', S.ellipsis(7));
                this.is('hello', S.ellipsis(-2));

                var S = 'multiple\nline\n\t string';
                this.is(tail, S.ellipsis());
                this.is(tail, S.ellipsis(0));
                this.is('m' + tail, S.ellipsis(1));
                this.is('mult' + tail, S.ellipsis(4));
                this.is('multiple\nline' + tail, S.ellipsis(13));
                this.is(S.substring(0, S.length - 1) + tail, S.ellipsis(S.length - 1));
              }
            },
            {
              name: 'quote()',
              test: function(){
                this.is('""', ''.quote('"'));
                this.is("''", ''.quote("'"));
                this.is('"hello"', 'hello'.quote('"'));
                this.is("'hello'", 'hello'.quote("'"));
                this.is('<!--hello-->', 'hello'.quote('<!--', '-->'));
                this.is('[hello]', 'hello'.quote('['));
                this.is('(hello)', 'hello'.quote('('));
                this.is('<hello>', 'hello'.quote('<'));

                this.is('[he\\[l\\]lo]', 'he[l]lo'.quote('['));
                this.is('"he[\\"l\\"]lo"', 'he["l"]lo'.quote('"'));
                this.is('"he\'[\\"l\\"]\'lo"', 'he\'["l"]\'lo'.quote('"'));
              }
            },
            {
              name: 'capitalize()',
              test: function(){
                this.is('Foo', 'foo'.capitalize());
                this.is('Foo', 'fOO'.capitalize());
                this.is('Foobar', 'fooBar'.capitalize());
                this.is('Foo-bar', 'foo-bar'.capitalize());

                this.is("\u041F\u0440\u0438\u0432\u0435\u0442", "\u043F\u0440\u0438\u0432\u0435\u0442".capitalize());
                this.is("\u041F\u0440\u0438\u0432\u0435\u0442", "\u043F\u0440\u0438\u0412\u0435\u0442".capitalize());
              }
            },
            {
              name: 'camelize()',
              test: function(){
                this.is('foo', 'foo'.camelize());
                this.is('fooBar', 'foo-bar'.camelize());
                this.is('FooBar', '-foo-bar'.camelize());
                this.is('Foo', '-foo'.camelize());

                this.is("\u043F\u0440\u0438\u0432\u0435\u0442", "\u043F\u0440\u0438\u0432\u0435\u0442".camelize());
                this.is("\u043F\u0440\u0438\u0412\u0435\u0442", "\u043F\u0440\u0438-\u0432\u0435\u0442".camelize());
                this.is("\u041F\u0440\u0438\u0412\u0435\u0442", "-\u043F\u0440\u0438-\u0432\u0435\u0442".camelize());
                this.is("\u041F\u0440\u0438", "-\u043F\u0440\u0438".camelize());
              }
            },
            {
              name: 'dasherize()',
              test: function(){
                this.is('foo', 'foo'.dasherize());
                this.is('foo-bar', 'fooBar'.dasherize());
                this.is('-foo-bar', 'FooBar'.dasherize());
                this.is('-foo', 'Foo'.dasherize());

                // unicode unsupport
                //this.is("\u043F\u0440\u0438\u0432\u0435\u0442", "\u043F\u0440\u0438\u0432\u0435\u0442".dasherize());
                //this.is("\u043F\u0440\u0438-\u0432\u0435\u0442", "\u043F\u0440\u0438\u0412\u0435\u0442".dasherize());
                //this.is("-\u043F\u0440\u0438-\u0432\u0435\u0442", "\u041F\u0440\u0438\u0412\u0435\u0442".dasherize());
                //this.is("-\u043F\u0440\u0438", "\u041F\u0440\u0438".dasherize());
              }
            },
            {
              name: 'dump()',
              test: function(){
              
              }
            },
            {
              name: 'Buildin',
              testcase: [
                {
                  name: 'split()',
                  test: function(){
                  
                  }
                },
                {
                  name: 'replace()',
                  test: function(){
                  
                  }
                },
                {
                  name: 'substr()',
                  test: function(){
                  
                  }
                }
              ]
            }
          ]
        },
        {
          name: 'Number',
          testcase: [
            {
              name: 'toFixed()',
              test: function(){
                var N = 5;
                this.is('5', N.toFixed());
                this.is('5', N.toFixed(0));
                this.is('5.0', N.toFixed(1));
                this.is('5.00', N.toFixed(2));
                this.is('5.000', N.toFixed(3));

                var N = 5.1;
                this.is('5', N.toFixed());
                this.is('5', N.toFixed(0));
                this.is('5.1', N.toFixed(1));
                this.is('5.10', N.toFixed(2));
                this.is('5.100', N.toFixed(3));

                var N = 5.12345;
                this.is('5', N.toFixed());
                this.is('5', N.toFixed(0));
                this.is('5.1', N.toFixed(1));
                this.is('5.12', N.toFixed(2));
                this.is('5.123', N.toFixed(3));
                this.is('5.12345', N.toFixed(5));
                this.is('5.1234500', N.toFixed(7));
              }
            },/* removed from Basis
            {
              name: 'toBin()',
              test: function(){
                var N = 0;
                this.is('0', (0).toBin());
                this.is('1', (1).toBin());
                this.is('10', (2).toBin());
                this.is('10', (2.5).toBin());
                this.is('11', (3).toBin());
                this.is('101', (5).toBin());
                this.is('1111111', (127).toBin());
                this.is('10000000', (128).toBin());
                this.is('11111111', (255).toBin());
                this.is('1001001100101100000001011010010', (1234567890).toBin());
                this.is('-1', (-1).toBin());
                this.is('-1010', (-10).toBin());
                this.is('-1010', (-10.5).toBin());
              }
            },*/
            {
              name: 'quote',
              test: function(){
                var N = 5;
                this.is('"5"', N.quote('"'));
                this.is('(5)', N.quote('('));
                this.is('<!--5-->', N.quote('<!--', '-->'));

                var N = 5.2;
                this.is('"5.2"', N.quote('"'));
                this.is('(5.2)', N.quote('('));

                var N = -5;
                this.is('"-5"', N.quote('"'));
                this.is('(-5)', N.quote('('));

                var N = -5.3;
                this.is('"-5.3"', N.quote('"'));
                this.is('(-5.3)', N.quote('('));
              }
            },
            {
              name: 'base()',
              test: function(){
                var N = 7;
                this.is(6, N.base(6));
                this.is(5, N.base(5));
                this.is(4, N.base(4));
                this.is(6, N.base(3));
                this.is(6, N.base(2));
                this.is(7, N.base(1));

                var N = -7;
                this.is(-12, N.base(6));
                this.is(-10, N.base(5));
                this.is(-8, N.base(4));
                this.is(-9, N.base(3));
                this.is(-8, N.base(2));
                this.is(-7, N.base(1));
              }
            },
            {
              name: 'group',
              test: function(){
                var N = 1;
                this.is('1', N.group());
                this.is('1', N.group(5));

                var N = -1;
                this.is('-1', N.group());
                this.is('-1', N.group(5));

                var N = 1234567890;
                this.is('1 234 567 890', N.group());
                this.is('12 34 56 78 90', N.group(2));
                this.is('1 234 567 890', N.group(3));
                this.is('12 3456 7890', N.group(4));
                this.is('1234567890', N.group(10));
                this.is('1234567890', N.group(15));

                this.is('1-234-567-890', N.group(undefined, '-'));
                this.is('1-234-567-890', N.group(3, '-'));

                var N = -1234567890;
                this.is('-1 234 567 890', N.group());
                this.is('-12 34 56 78 90', N.group(2));
                this.is('-1 234 567 890', N.group(3));
                this.is('-12 3456 7890', N.group(4));
                this.is('-1234567890', N.group(10));
                this.is('-1234567890', N.group(15));

                this.is('-1-234-567-890', N.group(undefined, '-'));
                this.is('-1-234-567-890', N.group(3, '-'));

                var N = 1.1;
                this.is('1.1', N.group());
                this.is('1.1', N.group(1));
                this.is('1.1', N.group(2));
                this.is('1.1', N.group(5));

                var N = -1.1;
                this.is('-1.1', N.group());
                this.is('-1.1', N.group(1));
                this.is('-1.1', N.group(2));
                this.is('-1.1', N.group(5));

                var N = 1234567890.12345;
                this.is('1 234 567 890.12345', N.group());
                this.is('12 34 56 78 90.12345', N.group(2));
                this.is('1 234 567 890.12345', N.group(3));
                this.is("1'234'567'890.12345", N.group(3, "'"));
                this.is('12 3456 7890.12345', N.group(4));
                this.is('1234567890.12345', N.group(10));
                this.is('1234567890.12345', N.group(15));

                var N = -1234567890.12345;
                this.is('-1 234 567 890.12345', N.group());
                this.is('-12 34 56 78 90.12345', N.group(2));
                this.is('-1 234 567 890.12345', N.group(3));
                this.is("-1'234'567'890.12345", N.group(3, "'"));
                this.is('-12 3456 7890.12345', N.group(4));
                this.is('-1234567890.12345', N.group(10));
                this.is('-1234567890.12345', N.group(15));
              }
            },
            {
              name: 'toHex()',
              test: function(){
                this.is('FF', (255).toHex());
                this.is('A0', (160).toHex());
                this.is('263BD1', (2505681).toHex());
              }
            },
            {
              name: 'lead()',
              test: function(){
                var N = 123;
                this.is('123', N.lead());
                this.is('123', N.lead(0));
                this.is('123', N.lead(1));
                this.is('123', N.lead(2));
                this.is('123', N.lead(3));
                this.is('00123', N.lead(5));
                this.is('##123', N.lead(5, '#'));

                var N = -123;
                this.is('-123', N.lead());
                this.is('-123', N.lead(0));
                this.is('-123', N.lead(1));
                this.is('-123', N.lead(2));
                this.is('-123', N.lead(3));
                this.is('-00123', N.lead(5));
                this.is('-##123', N.lead(5, '#'));

                var N = 123.23;
                this.is('123.23', N.lead());
                this.is('123.23', N.lead(0));
                this.is('123.23', N.lead(1));
                this.is('123.23', N.lead(2));
                this.is('123.23', N.lead(3));
                this.is('123.23', N.lead(6));
                this.is('00123.23', N.lead(8));
                this.is('##123.23', N.lead(8, '#'));

                var N = -123.23;
                this.is('-123.23', N.lead());
                this.is('-123.23', N.lead(0));
                this.is('-123.23', N.lead(1));
                this.is('-123.23', N.lead(2));
                this.is('-123.23', N.lead(3));
                this.is('-123.23', N.lead(6));
                this.is('-00123.23', N.lead(8));
                this.is('-##123.23', N.lead(8, '#'));
              }
            }
          ]
        }
      ];

    })());

//    if (top.nextTest)
//      top.nextTest();

  </script>
</body>

</html>